package net.aiion.weave.spi.bytecode;

import net.aiion.weave.asm.Attribute;
import net.aiion.weave.asm.Handle;
import net.aiion.weave.asm.Label;
import net.aiion.weave.spi.bytecode.events.AnnotationAnnotationValueBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.AnnotationArrayValueBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.AnnotationDefaultStartBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.AnnotationEndBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.AnnotationEnumValueBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.AnnotationStartBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.AnnotationValueBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.AttributeBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.ClassEndBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.ClassStartBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.CodeEndBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.CodeStartBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.FieldEndBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.FieldInstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.FieldStartBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.FrameBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.IincInstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.InnerClassBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.InstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.IntInstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.InvokeDynamicInstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.JumpInstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.LabelBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.LineNumberBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.LoadConstantInstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.LocalVariableBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.LookupSwitchInstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.MethodEndBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.MethodInstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.MethodStartBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.MultiANewArrayInstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.OuterClassBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.ParameterAnnotationStartBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.SourceBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.TableSwitchInstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.TryCatchBlockBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.TypeInstructionBytecodeEvent;
import net.aiion.weave.spi.bytecode.events.VariableInstructionBytecodeEvent;

public interface BytecodeEventFactory {
    ClassEndBytecodeEvent createClassEnd();

    MethodEndBytecodeEvent createMethodEnd();

    CodeEndBytecodeEvent createCodeEnd(int aMaximumStackSize, int aMaximumLocalVariables);

    LineNumberBytecodeEvent createLineNumber(int aLineNumber, Label aStartLabel);

    LocalVariableBytecodeEvent createLocalVariable(String aName, String aDescriptor, String aSignature,
        Label aStartScopeLabel, Label aEndScopeLabel, int aLocalVariableIndex);

    TryCatchBlockBytecodeEvent createTryCatchBlock(Label aStartLabel, Label aEndLabel, Label aHandlerLabel,
        String aExceptionName);

    LabelBytecodeEvent createLabel(Label aLabel);

    VariableInstructionBytecodeEvent createVariableInstruction(int aOpcode, int aLocalVariableIndex);

    TypeInstructionBytecodeEvent createTypeInstruction(int aOpcode, String aTypeName);

    TableSwitchInstructionBytecodeEvent createTableSwitchInstruction(int aMinimumKeyValue, int aMaximumKeyValue,
        Label aDefaultLabel, Label[] aBlockLabels);

    MultiANewArrayInstructionBytecodeEvent createMultiANewArrayInstruction(String aComponentDescriptor, int aDimensions);

    MethodInstructionBytecodeEvent createMethodInstruction(int aOpcode, String aOwnerName, String aMethodName,
        String aMethodDescriptor);

    LookupSwitchInstructionBytecodeEvent createLookupSwitchInstruction(Label aDefaultLabel, int[] aKeys,
        Label[] aBlockLabels);

    LoadConstantInstructionBytecodeEvent createLoadConstantInstruction(Object aConstant);

    JumpInstructionBytecodeEvent createJumpInstruction(int aOpcode, Label aLabel);

    InvokeDynamicInstructionBytecodeEvent createInvokeDynamicInstruction(String aMethodName, String aMethodDescriptor,
        Handle aBootstrapMethodHandle, Object[] aBootstrapMethodArguments);

    IntInstructionBytecodeEvent createIntInstruction(int aOpcode, int aOperand);

    InstructionBytecodeEvent createInstruction(int aOpcode);

    IincInstructionBytecodeEvent createIincInstruction(int aLocalVariableIndex, int aIncrement);

    FieldInstructionBytecodeEvent createFieldInstruction(int aOpcode, String aOwnerName, String aFieldName,
        String aFieldDescriptor);

    FrameBytecodeEvent createFrame(int aFrameType, int aLocalVariables, Object[] aLocalVariableTypes,
        int aStackElements, Object[] aStackElementTypes);

    CodeStartBytecodeEvent createCodeStart();

    ParameterAnnotationStartBytecodeEvent createParameterAnnotationStart(int aParameterIndex, String aDescriptor,
        boolean aVisible);

    AnnotationDefaultStartBytecodeEvent createAnnotationDefaultStart();

    MethodStartBytecodeEvent createMethodStart(int aModifiers, String aName, String aDescriptor, String aSignature,
        String[] aExceptionNames);

    FieldEndBytecodeEvent createFieldEnd();

    FieldStartBytecodeEvent createFieldStart(int aModifiers, String aName, String aDescriptor, String aSignature,
        Object aConstantValue);

    InnerClassBytecodeEvent createInnerClass(String aInnerName, String aOuterName, String aInnerSimpleName,
        int aModifiers);

    AttributeBytecodeEvent createAttribute(Attribute aAttribute);

    AnnotationEndBytecodeEvent createAnnotationEnd();

    AnnotationArrayValueBytecodeEvent createAnnotationArrayValue(String aName);

    AnnotationAnnotationValueBytecodeEvent createAnnotationAnnotationValue(String aName, String aDescriptor);

    AnnotationEnumValueBytecodeEvent createAnnotationEnumValue(String aName, String aDescriptor, String aValue);

    AnnotationValueBytecodeEvent createAnnotationValue(String aName, Object aValue);

    AnnotationStartBytecodeEvent createAnnotationStart(String aDescriptor, boolean aVisible);

    OuterClassBytecodeEvent createOuterClass(String aEnclosingClassName, String aMethodName, String aMethodDescriptor);

    SourceBytecodeEvent createSource(String aSourceFileName, String aDebugInformation);

    ClassStartBytecodeEvent createClassStart(int aVersion, int aModifiers, String aName, String aSignature,
        String aSuperName, String[] aInterfaceNames);
}
